#include <linux/kernel.h>
#include <linux/module.h>

/**
 * @brief 打印当前栈帧的信息
 * 
 * 该函数获取当前栈帧指针并打印前一个栈帧的信息，包括上一帧指针、返回地址和函数的第一个参数。
 */
void print_stack_frame(void) {
    unsigned long *ebp;
    
    // 获取当前帧指针
    asm("mov %%rbp, %0" : "=r"(ebp));
    
    // 打印上一个栈帧的信息
    printk(KERN_INFO "Previous frame pointer: %p\n", (void *)ebp);
    printk(KERN_INFO "Return address: %p\n", (void *)*(ebp + 1));
    printk(KERN_INFO "Function argument 1: %lx\n", *(ebp + 2)); // 注意：根据具体的函数调用，参数数量和类型可能需要调整。
}

/**
 * @brief 模块加载函数
 * 
 * 当模块被加载时调用该函数，打印模块加载信息并调用print_stack_frame函数。
 * 
 * @return int 返回0表示模块成功加载
 */
static int __init my_module_init(void) {
    printk(KERN_INFO "Module loaded.\n");
    print_stack_frame();
    return 0;
}

/**
 * @brief 模块卸载函数
 * 
 * 当模块被卸载时调用该函数，打印模块卸载信息。
 */
static void __exit my_module_exit(void) {
    printk(KERN_INFO "Module unloaded.\n");
}

module_init(my_module_init);
module_exit(my_module_exit);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("A simple kernel module to print stack frame information.");
MODULE_AUTHOR("Zhenxiong Chen");
